package com.example.port.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceUtils;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 数据库工具类
 */
public class DatabaseUtils {
    
    private static final Logger logger = LoggerFactory.getLogger(DatabaseUtils.class);
    
    /**
     * 获取数据库连接
     *
     * @param dataSource 数据源
     * @return 数据库连接
     */
    public static Connection getConnection(DataSource dataSource) {
        return DataSourceUtils.getConnection(dataSource);
    }
    
    /**
     * 释放数据库连接
     *
     * @param dataSource 数据源
     * @param connection 数据库连接
     */
    public static void releaseConnection(Connection connection, DataSource dataSource) {
        DataSourceUtils.releaseConnection(connection, dataSource);
    }
    
    /**
     * 执行查询并返回结果集合
     *
     * @param jdbcTemplate JDBC模板
     * @param sql          SQL语句
     * @param params       参数
     * @return 结果集合
     */
    public static List<Map<String, Object>> queryForList(JdbcTemplate jdbcTemplate, String sql, Object... params) {
        try {
            return jdbcTemplate.queryForList(sql, params);
        } catch (Exception e) {
            logger.error("执行查询出错: {}", e.getMessage(), e);
            return new ArrayList<>();
        }
    }
    
    /**
     * 执行查询并返回单个结果
     *
     * @param jdbcTemplate JDBC模板
     * @param sql          SQL语句
     * @param params       参数
     * @return 单个结果
     */
    public static Map<String, Object> queryForMap(JdbcTemplate jdbcTemplate, String sql, Object... params) {
        try {
            return jdbcTemplate.queryForMap(sql, params);
        } catch (Exception e) {
            logger.error("执行查询出错: {}", e.getMessage(), e);
            return new HashMap<>();
        }
    }
    
    /**
     * 执行更新操作
     *
     * @param jdbcTemplate JDBC模板
     * @param sql          SQL语句
     * @param params       参数
     * @return 影响行数
     */
    public static int update(JdbcTemplate jdbcTemplate, String sql, Object... params) {
        try {
            return jdbcTemplate.update(sql, params);
        } catch (Exception e) {
            logger.error("执行更新出错: {}", e.getMessage(), e);
            return 0;
        }
    }
    
    /**
     * 执行批量更新操作
     *
     * @param jdbcTemplate JDBC模板
     * @param sql          SQL语句
     * @param batchArgs    批量参数
     * @return 影响行数数组
     */
    public static int[] batchUpdate(JdbcTemplate jdbcTemplate, String sql, List<Object[]> batchArgs) {
        try {
            return jdbcTemplate.batchUpdate(sql, batchArgs);
        } catch (Exception e) {
            logger.error("执行批量更新出错: {}", e.getMessage(), e);
            return new int[0];
        }
    }
    
    /**
     * 关闭ResultSet
     *
     * @param rs ResultSet
     */
    public static void closeResultSet(ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                logger.error("关闭ResultSet出错: {}", e.getMessage(), e);
            }
        }
    }
    
    /**
     * 关闭PreparedStatement
     *
     * @param ps PreparedStatement
     */
    public static void closePreparedStatement(PreparedStatement ps) {
        if (ps != null) {
            try {
                ps.close();
            } catch (SQLException e) {
                logger.error("关闭PreparedStatement出错: {}", e.getMessage(), e);
            }
        }
    }
    
    /**
     * 关闭Connection
     *
     * @param conn Connection
     */
    public static void closeConnection(Connection conn) {
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                logger.error("关闭Connection出错: {}", e.getMessage(), e);
            }
        }
    }
    
    /**
     * 完整关闭数据库资源
     *
     * @param rs   ResultSet
     * @param ps   PreparedStatement
     * @param conn Connection
     */
    public static void closeAll(ResultSet rs, PreparedStatement ps, Connection conn) {
        closeResultSet(rs);
        closePreparedStatement(ps);
        closeConnection(conn);
    }
}
